package com.zywl.api;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONUtil;
import com.zywl.core.beans.AlipayFlow;
import com.zywl.service.AlipayFlowService;
import com.zywl.utils.utils.AesUtil;
import com.zywl.web.controller.base.BaseController;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 支付反馈接口
 */
@RestController
@RequestMapping("/api/pay/")
public class PayFeedBackApi extends BaseController {
    @Autowired
    private AlipayFlowService alipayFlowService;

    @ResponseBody
    @RequestMapping("feedback")
    public void feedback(HttpServletRequest request,HttpServletResponse response){
        logger.info("接收通知开始");
        Date date = new Date();
        try {
            String plainText = notify(request, response, "zhejiangshengwwwysconsultationcn");
            logger.info("plainText====" + plainText);
            JSONObject jsonObject = JSONObject.fromObject(plainText);

            String out_trade_no = jsonObject.getString("out_trade_no");
            String trade_state = jsonObject.getString("trade_state");
            String success_time = jsonObject.getString("success_time");

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
            Date date1 = sdf.parse(success_time);
//            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            String dateString = sdf2.format(date1);
//            System.out.println("date:"+dateString);
//            logger.info("out_trade_no"+out_trade_no);
            // 查询支付流水表
           Map<String, Object> flowWhereMap = new HashMap<>();
            flowWhereMap.put("afw_flow_no", out_trade_no);
            flowWhereMap.put("afw_stt", "0");

            List<AlipayFlow> alipayFlowList = alipayFlowService.getListByParams(flowWhereMap);

            if (alipayFlowList != null && !alipayFlowList.isEmpty()) {
                AlipayFlow alipayFlow = alipayFlowList.get(0);
                if(alipayFlow.getAfwRetTradeStatus() == null || !alipayFlow.getAfwRetTradeStatus().equals("SUCCESS")){
                    alipayFlow.setAfwRetNotifyTime(date1);
                    alipayFlow.setAfwRetTradeStatus(trade_state);
                    alipayFlow.setAfwModifyTime(date);
                    alipayFlowService.update(alipayFlow);
                }
            }
            logger.info("业务修改成功");
        }catch (Exception e){
            logger.error("业务回调异常",e);
        }
        logger.info("接收通知结束");
    }

    /**
     * 处理微信异步回调
     *
     * @param request
     * @param response
     * @param privateKey 32的秘钥
     */
    public static String notify(HttpServletRequest request, HttpServletResponse response, String privateKey) throws Exception {
        Map<String, String> map = new HashMap<>(12);
        String result = readData(request);
        // 需要通过证书序列号查找对应的证书，verifyNotify 中有验证证书的序列号
        String plainText = verifyNotify(result, privateKey);
        if (StrUtil.isNotEmpty(plainText)) {
            response.setStatus(200);
            map.put("code", "SUCCESS");
            map.put("message", "SUCCESS");
        } else {
            response.setStatus(500);
            map.put("code", "ERROR");
            map.put("message", "签名错误");
        }
        response.setHeader("Content-type", ContentType.JSON.toString());
        response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
        response.flushBuffer();
//        String out_trade_no = JSONObject.fromObject(plainText).getString("out_trade_no");
        return plainText;
    }

    /**
     * 处理返回对象
     *
     * @param request
     * @return
     */
    static String readData(HttpServletRequest request) {
        BufferedReader br = null;
        try {
            StringBuilder result = new StringBuilder();
            br = request.getReader();
            for (String line; (line = br.readLine()) != null; ) {
                if (result.length() > 0) {
                    result.append("\n");
                }
                result.append(line);
            }
            return result.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * v3 支付异步通知验证签名
     *
     * @param body 异步通知密文
     * @param key  api 密钥
     * @return 异步通知明文
     * @throws Exception 异常信息
     */
    static String verifyNotify(String body, String key) throws Exception {
        // 获取平台证书序列号
        cn.hutool.json.JSONObject resultObject = JSONUtil.parseObj(body);
        cn.hutool.json.JSONObject resource = resultObject.getJSONObject("resource");
        String cipherText = resource.getStr("ciphertext");
        String nonceStr = resource.getStr("nonce");
        String associatedData = resource.getStr("associated_data");
        AesUtil aesUtil = new AesUtil(key.getBytes(StandardCharsets.UTF_8));
        // 密文解密
        return aesUtil.decryptToString(
                associatedData.getBytes(StandardCharsets.UTF_8),
                nonceStr.getBytes(StandardCharsets.UTF_8),
                cipherText
        );
    }
}
